package com.alan.netty.rpc.v1;

import com.alan.netty.rpc.common.RpcException;
import com.alan.netty.rpc.common.RpcRequest;
import com.alan.netty.rpc.common.RpcResponse;
import com.alan.netty.rpc.common.SerializerFactory;
import com.alan.netty.rpc.common.serialize.ProtosuffSerialize;
import org.springframework.util.StringUtils;

import java.util.UUID;
import java.util.concurrent.SynchronousQueue;

/**
 * @author weiBin
 * @date 2018/11/30
 */
public class CalculatorServiceProxy implements CalculatorService {
    private RpcClient client;

    public CalculatorServiceProxy(String host, int port) {
        this.client = new RpcClient();
        try {
            client.init(host, port, SerializerFactory.getSerializer());
        } catch (Exception e) {
            e.printStackTrace();
        }
    }

    /**
     * 发送rpcRequest报文 等待服务端响应 rpcResponse 报文
     *
     * @param rpcRequest
     * @return
     */
    private RpcResponse sendRpcRequest(RpcRequest rpcRequest) throws RpcException {
        String requestId = rpcRequest.getId();
        if (StringUtils.isEmpty(requestId)) {
            throw new RpcException("request id can`t null");
        }
        SynchronousQueue<RpcResponse> queue = new SynchronousQueue<>();
        RpcClient.putSynchronousQueue(requestId, queue);
        try {
            client.writeRpcRequest(rpcRequest);
            RpcResponse rpcResponse = queue.take();
            System.out.println("消费哈哈！！");
            return rpcResponse;
        } catch (InterruptedException e) {
            e.printStackTrace();
        }
        return null;
    }

    public void stop() {
        client.close();
    }

    @Override
    public double add(double op1, double op2) {
        //封装rpcRequest对象
        RpcRequest request = new RpcRequest();
        request.setId(UUID.randomUUID().toString());
        request.setServiceName(CalculatorService.class.getName());
        request.setMethodName("add");
        request.setParameterTypeNames(new String[]{double.class.getName(), double.class.getName()});
        request.setArgs(new Object[]{op1, op2});
        //rpc远程调用服务端
        RpcResponse rpcResponse = sendRpcRequest(request);
        return (double) rpcResponse.getResult();
    }

    @Override
    public double substract(double op1, double op2) {
        //封装rpcRequest对象
        RpcRequest request = new RpcRequest();
        request.setId(UUID.randomUUID().toString());
        request.setServiceName(CalculatorService.class.getName());
        request.setMethodName("substract");
        request.setParameterTypeNames(new String[]{double.class.getName(), double.class.getName()});
        request.setArgs(new Object[]{op1, op2});
        //rpc远程调用服务端
        RpcResponse rpcResponse = sendRpcRequest(request);
        return (double) rpcResponse.getResult();
    }

    @Override
    public double multiply(double op1, double op2) {
        //封装rpcRequest对象
        RpcRequest request = new RpcRequest();
        request.setId(UUID.randomUUID().toString());
        request.setServiceName(CalculatorService.class.getName());
        request.setMethodName("multiply");
        request.setParameterTypeNames(new String[]{double.class.getName(), double.class.getName()});
        request.setArgs(new Object[]{op1, op2});
        //rpc远程调用服务端
        RpcResponse rpcResponse = sendRpcRequest(request);
        return (double) rpcResponse.getResult();
    }
}
